home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / icons+tools / picticon / source / doloaddt.e < prev    next >
Text File  |  1995-12-22  |  51KB  |  1,686 lines

  1. /*
  2.     DoLoadDT.m  --  A datatype load, scale, remap and dither routine.
  3. */   
  4. /* $VER:doloaddt 0.88 (7.6.95) */
  5.  
  6. /*
  7.  
  8. THIS SOURCE IS COPYRIGHT 1994,1995 by Chad Randall, mbissaymssiK Software
  9.  
  10. If you wish to include this, or any modified version of this routine in your
  11. own program, you *MUST* credit me somewhere in your program and/or documentation.
  12.  
  13. I am distributing this source mainly for those who wish to learn a thing or two.
  14.  
  15. Please don't rip me off.
  16.  
  17. */
  18.  
  19.  
  20. OPT MODULE
  21.  
  22. OPT PREPROCESS
  23.  
  24. MODULE    'exec/memory','exec/types'
  25. MODULE    'dos/dos'
  26. MODULE    'intuition/intuition','intuition/screens','intuition/gadgetclass'
  27. MODULE    'graphics/rastport','graphics/gfx','graphics/text','graphics/scale','graphics/view',
  28.                 'graphics/gfxbase','graphics/clip','graphics/layers','graphics/modeid'
  29. MODULE    'iffparse','libraries/iffparse'
  30. MODULE    'utility','utility/hooks','utility/tagitem'
  31. MODULE    'datatypes','datatypes/datatypes','datatypes/datatypesclass','datatypes/pictureclass'
  32. MODULE    'mathffp'
  33. MODULE    'gadtools','libraries/gadtools'
  34.  
  35. MODULE    'tools/boopsi'
  36.  
  37. MODULE    'mod/fonts'
  38. MODULE    'mod/bits'
  39. MODULE    'mod/compare'
  40. MODULE    'mod/gadgets'
  41. MODULE    'mod/gauge'
  42. MODULE    'mod/macros'
  43. MODULE    'mod/pool'
  44. MODULE    'mod/color'
  45.  
  46. EXPORT OBJECT statwindow
  47.     scr:PTR TO screen
  48.     centerx:INT
  49.     centery:INT
  50.     textfont:PTR TO textfont
  51.     textattr:PTR TO textattr
  52.     textstyle:LONG
  53.     load_string:LONG
  54.     scale_string:LONG
  55.     histogram_string:LONG
  56.     quant_string:LONG
  57.     render_string:LONG
  58.     cancel_string:LONG
  59.     title_string:LONG
  60.     status_string:LONG
  61. ENDOBJECT
  62.  
  63. EXPORT OBJECT gauge
  64.     rast:PTR TO rastport
  65.     scr:PTR TO screen
  66.     x:INT
  67.     y:INT
  68.     w:INT
  69.     h:INT
  70. ENDOBJECT
  71.  
  72. EXPORT OBJECT imageinfo
  73.     source_w:LONG
  74.     source_h:LONG
  75.     destination_x:LONG
  76.     destination_y:LONG
  77.     destination_w:LONG
  78.     destination_h:LONG
  79.     depth:LONG
  80.     highest_pen:LONG
  81.     statwindowx:LONG
  82.     statwindowy:LONG
  83.     reserved3:LONG
  84.     reserved4:LONG
  85.     reserved5:LONG
  86.     reserved6:LONG
  87.     reserved7:LONG
  88.     reserved8:LONG
  89.     blackpen:LONG
  90.     whitepen:LONG
  91.     greypen:LONG
  92. ENDOBJECT
  93.  
  94. /*OBJECT ditherarray
  95.     p1:CHAR
  96.     p2:CHAR
  97.     p3:CHAR
  98.     p4:CHAR
  99.     p5:CHAR
  100.     p6:CHAR
  101.     p7:CHAR
  102.     p8:CHAR
  103.     p9:CHAR
  104.     p10:CHAR
  105.     p11:CHAR
  106.     p12:CHAR
  107.     dividend:CHAR
  108. ENDOBJECT*/
  109.  
  110. EXPORT ENUM DLDT_CENTER=TAG_USER,            ->Centers image in w/h
  111.                         DLDT_INTEGERSCALE,                ->Does integer scaling routines.    NOT FASTER, but may look better.
  112.                         DLDT_DITHER,                            ->If =true then FS dithering is done
  113.                         DLDT_REMAP,                                ->Use FindColor to remap pens?
  114.                         DLDT_ASPECTX,                            ->x aspect value as in x:y
  115.                         DLDT_ASPECTY,                            ->y aspect value
  116.                         DLDT_SCALE,                                ->Should we scale, or crop? if=false then crop.
  117.                         DLDT_USEASPECT,                        ->Should we use the aspect values, or do 1:1 to 1:1?
  118.                         DLDT_ENLARGE,                            ->NOT IMPLEMENTED YET
  119.                         DLDT_CLEAR,                                ->Clears from x->y, w->h
  120.                         DLDT_GAUGE,                                ->A gauge struct.
  121.                         DLDT_CLIGAUGE,                        ->A ptr to a STRING with an imbedded "%s" code.
  122.                         DLDT_HOOK,                                ->A PROCedure (E!) to call periodically.
  123.                         DLDT_INFO,                                ->A ptr to a imageinfo struct to be filled in.
  124.                         DLDT_BIDIRECTIONAL,                ->NOT IMPLEMENTED
  125.                         DLDT_DIARRAY,                            ->NOT IMPLEMENTED
  126.                         DLDT_HIGHPEN,                            ->Highest pen to use, -1 for all available. (default)
  127.                         DLDT_FILLCMAP,                        -> Use DT cmap, and fill-in given cmap! no faint-hearts!!!
  128.                         DLDT_GREYSCALE,                        -> create greyscale icon
  129.                         DLDT_QUANTIZE,                            -> quantize to x number of colors
  130.                         DLDT_CUSTOMFINDCOLOR,            ->Use custom routine! OUCH
  131.                         DLDT_RENDERHAM,                        -> if =6 then HAM6, if =8 then HAM8, else normal
  132.                         DLDT_HAMTHRESHOLD,                -> specifies when to use base-4 colors
  133.                         DLDT_FULLHAMBASE,
  134.                         DLDT_DISCARDERROR,
  135.                         DLDT_STRETCHTOFIT,
  136.                         DLDT_NORENDER,
  137.                         DLDT_STATWINDOW,
  138.                         DLDT_ACTIVATESTATWINDOW,
  139.                         DLDT_DITHERTYPE,
  140.                         DLDT_QUANTTYPE
  141.  
  142. EXPORT ENUM DITH_ERRORDIFF,DITH_FLOYD,DITH_STUCKI,DITH_BURKES
  143. EXPORT ENUM QUANT_VERBATIM,QUANT_POPULARITY,QUANT_MEDIANCUT
  144.  
  145. DEF dtlib,utillib,ifflib,mathlib
  146.  
  147.  
  148. #define PPM_GETR(p) (Shr(Shr(((p) AND $FF0000),8),8))
  149. #define PPM_GETG(p) (Shr(((p) AND $FF00),8))
  150. #define PPM_GETB(p) ((p) AND $FF)
  151.  
  152. #define PPM_PUTR(red) (Shl(Shl(((red) AND $FF),8),8))
  153. #define PPM_PUTG(grn) (Shl(((grn) AND $FF),8))
  154. #define PPM_PUTB(blu) ((blu) AND $FF)
  155.  
  156. #define PPM_ASSIGN(red,grn,blu) ((Shl(Shl(red AND $FF,8),8)) OR (Shl(grn AND $FF,8)) OR (blu AND $FF))
  157.  
  158. OBJECT box
  159.     ind:INT
  160.     colors:INT
  161.     sum:LONG
  162.     redw:CHAR
  163.     grnw:CHAR
  164.     bluw:CHAR
  165. ENDOBJECT
  166.  
  167. CONST HASH_SIZE=20023
  168. CONST MAXCOLORS=32767
  169. #define HASHPIXEL(p) (Mod(((p) AND $ffffff),HASH_SIZE))
  170.  
  171. OBJECT colorhist_item
  172.     color:LONG
  173.     value:LONG
  174. ENDOBJECT
  175.  
  176. OBJECT colorhist_list_item
  177.     ch:colorhist_item
  178.     next:PTR TO colorhist_list_item
  179. ENDOBJECT
  180.  
  181. DEF statwindow:PTR TO window
  182. DEF statgauge
  183. DEF stat:PTR TO statwindow
  184. DEF histopool
  185.  
  186. EXPORT PROC doloaddt(source,rast:PTR TO rastport,cmap:PTR TO colormap,x,y,w,h,taglist=0) HANDLE
  187.     DEF dtf=NIL:PTR TO dtframebox,fri=NIL:PTR TO frameinfo,obj=NIL:PTR TO datatypeheader,gpl=NIL:PTR TO gplayout
  188.     DEF dtrast=NIL:PTR TO rastport
  189.     DEF red[260]:LIST,grn[260]:LIST,blu[260]:LIST
  190.     DEF tag:PTR TO tagitem
  191.     DEF cregs,bm=NIL:PTR TO bitmap,bmhd=NIL:PTR TO bitmapheader,numcolors,modeid
  192.     DEF norender=FALSE
  193.     DEF center=FALSE,intscale=FALSE,dither=TRUE,remap=TRUE,aspectx=1,aspecty=1,scale=TRUE,useaspect=TRUE,enlarge=FALSE,clear=TRUE
  194.     DEF scalex,scaley,scalef
  195.     DEF res,res2
  196.     DEF trast=NIL:PTR TO rastport,tbm=NIL:PTR TO bitmap
  197.     DEF sfixx,sfixy
  198.     DEF ditz=0,dang=0,dumb=0,body
  199.     DEF usehighpen=-1
  200.     DEF fillcmap=FALSE
  201.     DEF cm
  202.     DEF hammode=FALSE,gauge=FALSE:PTR TO gauge,gaugestr=FALSE,hook=0
  203.     DEF i,t,u,v,z,xpixper=1,ypixper=1,step,stop
  204.     DEF scalarx,scalary,percent,adjustw,adjusth,finalw,finalh,finalx,finaly
  205.     DEF linebuf=0,redbuf=0,grnbuf=0,blubuf=0
  206.     DEF dithermode=DITH_FLOYD
  207.     DEF r38,g38,b38,r39,g39,b39
  208.     DEF stretch=FALSE
  209.     DEF statx=0,staty=0,statw=0,stath=0
  210.     DEF statgad=0
  211.     DEF glist=0,gad
  212.     DEF tmp1=0,tmp2=0,tmp3=0,tmp4=0,tmp5,tmp6,tmp7,tmp8,ttmp1,ttmp2,ttmp3
  213.     DEF lmp4,lmp5,lmp6
  214.     DEF er1,er2,er3,er4
  215.     DEF eg1,eg2,eg3,eg4
  216.     DEF eb1,eb2,eb3,eb4
  217.     DEF sumred=0,sumgrn=0,sumblu=0,num=0
  218.     DEF fc,reddif,grndif,bludif,grabbuf
  219.     DEF realred[260]:LIST,realgrn[260]:LIST,realblu[260]:LIST
  220.     DEF drawinfo=NIL:PTR TO drawinfo
  221.     DEF vis=0
  222.     DEF iinfo=0:PTR TO imageinfo
  223.     DEF highpen=0
  224.     DEF activatewindow=FALSE
  225.     DEF speed1,speed2,speed3,speed4,speed5,speed6,speed7,speed8
  226.     DEF red24=0,grn24=0,blu24=0
  227.     DEF grey=0,quant=256
  228.     DEF hamr,hamg,hamb
  229.     DEF hadr,hadg,hadb
  230.     DEF renderham=0,hamthres=64
  231.     DEF hambase=3
  232.     DEF discard=FALSE
  233.     DEF quantmode=QUANT_MEDIANCUT
  234.     DEF histo
  235. ->    WriteF('\n Start AVAILMEM-\d\n',AvailMem(MEMF_ANY))
  236.  
  237.     histo:=0;statwindow:=0;statgauge:=0;stat:=0
  238.  
  239.     dtf:=New(600);fri:=New(600);gpl:=New(600)
  240.  
  241.     dtrast:=New(SIZEOF rastport);InitRastPort(dtrast)
  242.     trast:=New(SIZEOF rastport)
  243.  
  244.     CopyMem(dtrast,trast,SIZEOF rastport);trast.layer:=0
  245.     
  246.     IF checklibs()=FALSE THEN Raise("LIB")
  247.     IF taglist
  248.         IF (tag:=FindTagItem(DLDT_CENTER,taglist)) THEN center:=tag.data
  249.         IF (tag:=FindTagItem(DLDT_INTEGERSCALE,taglist)) THEN intscale:=tag.data
  250.         IF (tag:=FindTagItem(DLDT_DITHER,taglist)) THEN dither:=tag.data
  251.         IF (tag:=FindTagItem(DLDT_REMAP,taglist)) THEN remap:=tag.data
  252.         IF (tag:=FindTagItem(DLDT_ASPECTX,taglist)) THEN aspecty:=tag.data
  253.         IF (tag:=FindTagItem(DLDT_ASPECTY,taglist)) THEN aspectx:=tag.data
  254.         IF (tag:=FindTagItem(DLDT_SCALE,taglist)) THEN scale:=tag.data
  255.         IF (tag:=FindTagItem(DLDT_USEASPECT,taglist)) THEN useaspect:=tag.data
  256.         IF (tag:=FindTagItem(DLDT_ENLARGE,taglist)) THEN enlarge:=tag.data
  257.         IF (tag:=FindTagItem(DLDT_CLEAR,taglist)) THEN clear:=tag.data
  258.         IF (tag:=FindTagItem(DLDT_GAUGE,taglist)) THEN gauge:=tag.data
  259.         IF (tag:=FindTagItem(DLDT_CLIGAUGE,taglist)) THEN gaugestr:=tag.data
  260.         IF (tag:=FindTagItem(DLDT_HOOK,taglist)) THEN hook:=tag.data
  261.         IF (tag:=FindTagItem(DLDT_INFO,taglist)) THEN iinfo:=tag.data
  262.         IF (tag:=FindTagItem(DLDT_HIGHPEN,taglist)) THEN usehighpen:=tag.data
  263.         IF (tag:=FindTagItem(DLDT_FILLCMAP,taglist)) THEN fillcmap:=tag.data
  264.         IF (tag:=FindTagItem(DLDT_QUANTIZE,taglist)) THEN quant:=limit(tag.data,1,256)
  265.         IF (tag:=FindTagItem(DLDT_GREYSCALE,taglist)) THEN grey:=limit(tag.data,0,2)
  266.         IF (tag:=FindTagItem(DLDT_RENDERHAM,taglist)) THEN renderham:=limit(tag.data,0,8)
  267.         IF (tag:=FindTagItem(DLDT_HAMTHRESHOLD,taglist)) THEN hamthres:=limit(tag.data,0,760)
  268.         IF (tag:=FindTagItem(DLDT_FULLHAMBASE,taglist)) THEN IF (tag.data<>FALSE) THEN hambase:=IF (renderham=6) THEN 15 ELSE 63
  269.         IF (tag:=FindTagItem(DLDT_DISCARDERROR,taglist)) THEN discard:=tag.data
  270.         IF (tag:=FindTagItem(DLDT_STRETCHTOFIT,taglist)) THEN stretch:=tag.data
  271.         IF (tag:=FindTagItem(DLDT_NORENDER,taglist)) THEN norender:=tag.data
  272.         IF (tag:=FindTagItem(DLDT_STATWINDOW,taglist)) THEN stat:=tag.data
  273.         IF (tag:=FindTagItem(DLDT_ACTIVATESTATWINDOW,taglist)) THEN activatewindow:=tag.data
  274.         IF (tag:=FindTagItem(DLDT_DITHERTYPE,taglist)) THEN dithermode:=tag.data
  275.         IF (tag:=FindTagItem(DLDT_QUANTTYPE,taglist)) THEN quantmode:=tag.data
  276.  
  277.          IF usehighpen=-1 THEN usehighpen:=256
  278.         IF (quant<256)
  279.             usehighpen:=limit(smaller(usehighpen,quant-1),1,255)
  280.         ENDIF
  281.     ENDIF
  282.  
  283.      IF stat
  284.         drawinfo:=GetScreenDrawInfo(stat.scr)
  285.         vis:=GetVisualInfoA(stat.scr, NIL)
  286.     ENDIF
  287.  
  288.      IF (stat AND drawinfo AND vis)
  289.          statw,stath:=biggest(rast,[stat.load_string,stat.scale_string,stat.histogram_string,stat.render_string,TAG_END]:LONG,stat.textfont,stat.textstyle)
  290.          tmp1,tmp2:=fontsize2(rast,stat.cancel_string,stat.textfont,stat.textstyle)
  291.          tmp8,tmp7:=fontsize2(rast,stat.status_string,stat.textfont,stat.textstyle)
  292.          statw:=bigger(bigger(statw,tmp1),tmp8)
  293.         tmp8:=bigger(tmp8,statw)
  294.          statx:=stat.centerx-(statw/2)
  295.          staty:=stat.centery-(stath/2)
  296.          tmp3:=(WFLG_SMART_REFRESH OR WFLG_DRAGBAR OR WFLG_DEPTHGADGET)
  297.          IF activatewindow THEN tmp3:=tmp3 OR WFLG_ACTIVATE
  298.          statwindow:=OpenWindowTagList(0,
  299.                                      [WA_INNERWIDTH,statw+16,
  300.                                         WA_INNERHEIGHT,stath+26+tmp2+tmp7,
  301.                                         WA_LEFT,statx,
  302.                                         WA_TOP,staty,
  303.                                         WA_FLAGS,tmp3,
  304.                                         WA_TITLE,stat.title_string,
  305.                                         WA_CUSTOMSCREEN,stat.scr,
  306.                                         WA_IDCMP,(BUTTONIDCMP OR IDCMP_REFRESHWINDOW),
  307.                                         WA_NEWLOOKMENUS,TRUE,
  308.                                         WA_AUTOADJUST,TRUE,
  309.                                         NIL])
  310.         SetAPen(statwindow.rport,2)
  311.         SetBPen(statwindow.rport,0)
  312.         setafpt(statwindow.rport,[%1010101010101010,%0101010101010101]:INT,1)
  313.         SetDrMd(statwindow.rport,RP_JAM2)
  314.         RectFill(statwindow.rport,statwindow.borderleft,statwindow.bordertop,rightedge(statwindow)-1,bottomedge(statwindow)-1)
  315.         setafpt(statwindow.rport,0,0)
  316.         
  317.         IF statwindow
  318.             gad:=CreateContext({glist})
  319.              tmp3:=(statwindow.width/2)-(tmp1/2)
  320.              tmp4:=(statwindow.height-statwindow.borderbottom-tmp2-6)
  321.             statgad,gad:=CreateGadgetA(BUTTON_KIND,gad,
  322.                                                 [tmp3-6,tmp4,tmp1+12,tmp2+4,stat.cancel_string,stat.textattr,1,0,vis,0]:newgadget,[NIL,NIL])
  323.             AddGList(statwindow,statgad,-1,-1,0)
  324.             RefreshGList(statgad,statwindow,0,-1)
  325.             disablegadget(statgad,statwindow)
  326.             statgauge:=newgauge(statwindow.rport,statwindow.borderleft+2,statwindow.bordertop+10+tmp7,insidewidth(statwindow)-4,stath+8,stat.textfont,stat.textstyle,vis,drawinfo,GAUGETYPE_FANCY)
  327.             tmp1:=(statwindow.width/2)-(tmp8/2)
  328.             tmp2:=statwindow.bordertop+2
  329.             drawbevelbox(vis,statwindow.rport,tmp1-6,tmp2,tmp8+12,tmp7+4,1,TRUE,0)
  330.             Move(statwindow.rport,tmp1,stat.textfont.baseline+tmp2+2)
  331.             SetAPen(statwindow.rport,1)
  332.             SetFont(statwindow.rport,stat.textfont)
  333.             Text(statwindow.rport,stat.status_string,StrLen(stat.status_string))
  334.             statusgauge(statgauge,stat.load_string)
  335.         ENDIF
  336.      ENDIF
  337.  
  338.     IF source<257
  339.         obj:=NewDTObjectA(source,[DTA_SOURCETYPE,DTST_CLIPBOARD,DTA_GROUPID,GID_PICTURE,PDTA_REMAP,FALSE,NIL,NIL])
  340.     ELSE
  341.         obj:=NewDTObjectA(source,[DTA_SOURCETYPE,DTST_FILE,DTA_GROUPID,GID_PICTURE,PDTA_REMAP,FALSE,NIL,NIL])
  342.     ENDIF
  343.     IF obj
  344.         IF (drawinfo=0) THEN IF (gauge) THEN drawinfo:=GetScreenDrawInfo(gauge.scr)
  345.         PutLong(dtf,DTM_FRAMEBOX)
  346.         dtf.frameinfo:=fri
  347.         dtf.contentsinfo:=fri
  348.         dtf.sizeframeinfo:=SIZEOF frameinfo
  349.         IF (domethod(obj,dtf))
  350.             PutLong(gpl,DTM_PROCLAYOUT)
  351.             gpl.ginfo:=NIL
  352.             gpl.initial:=1
  353.             IF (domethod(obj,gpl))
  354.                 GetDTAttrsA(obj,[PDTA_CREGS,{cregs},PDTA_BITMAP,{bm},PDTA_NUMCOLORS,{numcolors},
  355.                         PDTA_BITMAPHEADER,{bmhd},PDTA_MODEID,{modeid},NIL,NIL])
  356.                 IF (modeid AND HAM_KEY);hammode:=TRUE;ENDIF
  357.                 dtrast.bitmap:=bm
  358.                 IF usehighpen=256 THEN usehighpen:=-1
  359.                 IF bm<>NIL
  360.                     body:=cregs
  361.                     FOR i:=0 TO (Shl(1,(bmhd.depth))-1)
  362.                         ditz:=Char(body);body:=body+4;red[i]:=ditz
  363.                         dang:=Char(body);body:=body+4;grn[i]:=dang
  364.                         dumb:=Char(body);body:=body+4;blu[i]:=dumb
  365.                     ENDFOR
  366. /*                    IF (fillcmap)
  367.                         IF (grey>0)
  368.                             speed2:=limit(smaller(quant,Shl(1,bmhd.depth)-1),1,255)
  369.                             FOR i:=0 TO speed2-1
  370.                                 speed1:=((((i*100)/(speed2-1))*256)/100)
  371.                                 r38:=limit(speed1,0,255)
  372.                                 r38:=Shl(r38,8) OR r38
  373.                                 r38:=Shl(r38,8) OR r38
  374.                                 r38:=Shl(r38,8) OR r38
  375.                                 SetRGB32CM(cmap,smaller(i,255),r38,r38,r38)
  376.                             ENDFOR
  377.                         ENDIF
  378.                     ENDIF*/
  379.                     grabbuf:=[0,0,0,0,0,0,0,0]:LONG
  380.  
  381.                     tbm:=AllocBitMap((bmhd.width*2),1,8,(BMF_CLEAR OR BMF_STANDARD),NIL)
  382.                     trast.bitmap:=tbm
  383.  
  384.                     adjustw:=SpFlt(bmhd.width)
  385.                     adjusth:=SpFlt(bmhd.height)
  386.                     IF ((useaspect<>FALSE) AND (intscale=FALSE))
  387.                         IF bmhd.xaspect=0 THEN bmhd.xaspect:=1
  388.                         IF bmhd.yaspect=0 THEN bmhd.yaspect:=1
  389.                         scalarx:=SpDiv(SpFlt(aspectx),SpFlt(bmhd.xaspect))
  390.                         scalary:=SpDiv(SpFlt(aspecty),SpFlt(bmhd.yaspect))
  391.  
  392.                         res:=SpCmp(scalarx,scalary)
  393.                         IF res<0    -> scaraly is GREATER THAN scalarx
  394.                             percent:=SpDiv(scalarx,scalary)
  395.                             adjusth:=SpMul(percent,SpFlt(bmhd.height))
  396.                         ELSE
  397.                             percent:=SpDiv(scalary,scalarx)
  398.                             adjustw:=SpMul(percent,SpFlt(bmhd.width))
  399.                         ENDIF
  400.                     ENDIF
  401.  
  402.                     finalx:=x;finaly:=y;finalw:=w;finalh:=h;scalex:=SpFlt(1);scaley:=SpFlt(1)
  403.  
  404.                     res:=SpCmp(SpFlt(w),adjustw)
  405.                     res2:=SpCmp(SpFlt(h),adjusth)
  406.                     IF (((res<0) OR (res2<0)) AND (scale<>FALSE))    -> Datatype is LARGER than workspace, so scale?
  407.                         IF (intscale<>FALSE)
  408.                             scalex:=SpFlt(SpFix( SpDiv(SpFlt(w),SpFlt(SpFix(adjustw)))))
  409.                             scaley:=SpFlt(SpFix( SpDiv(SpFlt(h),SpFlt(SpFix(adjusth)))))
  410.                             res:=SpCmp(scalex,scaley)
  411.                             IF (res<0);scalef:=scaley;ELSE;scalef:=scalex;ENDIF
  412.                             finalw:=SpFix(SpDiv(scalef,adjustw))
  413.                             finalh:=SpFix(SpDiv(scalef,adjusth))
  414.                         ELSE
  415.                             scalex:=SpDiv(SpFlt(w),adjustw)
  416.                             scaley:=SpDiv(SpFlt(h),adjusth)
  417.                             res:=SpCmp(scalex,scaley)
  418.                             IF (res<0);scalef:=scaley;ELSE;scalef:=scalex;ENDIF
  419.                             finalw:=SpFix(SpDiv(scalef,adjustw))
  420.                             finalh:=SpFix(SpDiv(scalef,adjusth))
  421.                         ENDIF
  422.                         IF (stretch)
  423.                             finalw:=smaller(bmhd.width,w);finalh:=smaller(bmhd.height,h)
  424. ->                            finalw:=w;finalh:=h
  425.                         ENDIF
  426.                         xpixper:=SpDiv(SpFlt(finalw),SpFlt(bmhd.width))
  427.                         ypixper:=SpDiv(SpFlt(finalh),SpFlt(bmhd.height))
  428.                     ELSE
  429.                         finalw:=smaller(bmhd.width,w);finalh:=smaller(bmhd.height,h)
  430.                         xpixper:=SpFlt(1);ypixper:=SpFlt(1)
  431.                     ENDIF
  432.                         
  433.                     IF center
  434.                         finalx:=x+(w/2)-(finalw/2)
  435.                         finaly:=y+(h/2)-(finalh/2)
  436.                     ENDIF
  437.  
  438.                     IF statgauge THEN cleargauge(statgauge)
  439.                     IF statgad THEN enablegadget(statgad,statwindow)
  440.  
  441.                     IF ((remap=FALSE) AND (scale=FALSE))
  442.                         FOR t:=0 TO finalh-1
  443.                             IF checkcancel(statwindow) THEN Raise("canc")
  444.                             IF (((t+3)/4) = (t/4))
  445.                                 IF statgauge THEN fuelgauge(statgauge,t,finalh-1,stat.render_string)
  446.                             ENDIF
  447.                             FOR i:=0 TO finalw-1
  448.                                 fc:=ReadPixel(dtrast,i,t)
  449.                                 WHILE fc>usehighpen
  450.                                     fc:=Shr(fc,1)
  451.                                 ENDWHILE
  452.                                 IF highpen<fc THEN highpen:=fc
  453.                                 SetAPen(rast,fc)
  454.                                 WritePixel(rast,finalx+i,finaly+t)
  455.                             ENDFOR
  456.                         ENDFOR
  457.                     ELSE
  458.                         redbuf:=New(bmhd.width*(SpFix(ypixper)*4)*2)
  459.                         grnbuf:=New(bmhd.width*(SpFix(ypixper)*4)*2)
  460.                         blubuf:=New(bmhd.width*(SpFix(ypixper)*4)*2)
  461.                         linebuf:=New(bmhd.width*8)
  462.  
  463.                         speed2:=bmhd.width-1
  464.                         speed3:=SpFix(ypixper)-1
  465.                         speed4:=(finalw*12)+64
  466.                         speed5:=finalw-1
  467.                         sfixx:=SpFix(xpixper)-1
  468.                         sfixy:=SpFix(ypixper)-1
  469.  
  470.                         red24:=New(finalw*(finalh+16))
  471.                         grn24:=New(finalw*(finalh+16))
  472.                         blu24:=New(finalw*(finalh+16))
  473.  
  474.                         FOR t:=0 TO (finalh-1)
  475.                             IF checkcancel(statwindow) THEN Raise("canc")
  476.                             IF (((t+3)/4) = (t/4))
  477.                                 IF statgauge THEN fuelgauge(statgauge,t,finalh-1,stat.scale_string)
  478.                             ENDIF
  479.  
  480.                             FOR u:=t TO t+speed3
  481.                                 ReadPixelLine8(dtrast,0,SpFix(SpMul(SpFlt(t),ypixper))+(u-t),bmhd.width,linebuf,trast)
  482.                                 speed8:=Char(linebuf)
  483.                                 tmp1:=red[speed8];tmp2:=grn[speed8];tmp3:=blu[speed8]
  484.                                 IF (hammode)
  485.                                     tmp1:=red[0];tmp2:=grn[0];tmp3:=blu[0]
  486.                                     IF bmhd.depth=8    -> HAM8
  487.                                         IF (speed8 AND %11000000)
  488.                                             IF ((speed8 AND %11000000)=%10000000)    -> Modify RED
  489.                                                 tmp1:=Shl((speed8 AND %111111),2);ENDIF
  490.                                             IF ((speed8 AND %11000000)=%01000000)    -> Modify BLUE
  491.                                                 tmp3:=Shl((speed8 AND %111111),2);ENDIF
  492.                                             IF ((speed8 AND %11000000)=%11000000)    -> Modify GRN
  493.                                                 tmp2:=Shl((speed8 AND %111111),2);ENDIF
  494.                                         ELSE
  495.                                             tmp1:=red[(speed8 AND %111111)];tmp2:=grn[(speed8 AND %111111)];tmp3:=blu[(speed8 AND %111111)]
  496.                                         ENDIF
  497.                                     ELSE
  498.                                         IF (speed8 AND %110000)
  499.                                             IF (speed8 AND %110000)=%100000    -> Modify RED
  500.                                                 tmp1:=Shl((speed8 AND %1111),4);ENDIF
  501.                                             IF (speed8 AND %110000)=%010000    -> Modify BLUE
  502.                                                 tmp3:=Shl((speed8 AND %1111),4);ENDIF
  503.                                             IF (speed8 AND %110000)=%110000    -> Modify GRN
  504.                                                 tmp2:=Shl((speed8 AND %1111),4);ENDIF
  505.                                         ELSE
  506.                                             tmp1:=red[(z AND %1111)];tmp2:=grn[(z AND %1111)];tmp3:=blu[(z AND %1111)]
  507.                                         ENDIF
  508.                                     ENDIF
  509.                                 ENDIF
  510.                                 speed1:=bmhd.width*(u-t)
  511.                                 ditz:=redbuf+speed1
  512.                                 dang:=grnbuf+speed1
  513.                                 dumb:=blubuf+speed1
  514.                                 IF (remap=FALSE) THEN ditz:=redbuf
  515.                                 FOR v:=1 TO bmhd.width
  516.                                     IF (remap=FALSE)
  517.                                         PutChar(ditz,Char(linebuf+v));ditz:=ditz+1
  518.                                     ELSE
  519.                                         PutChar(ditz,tmp1);ditz:=ditz+1
  520.                                         PutChar(dang,tmp2);dang:=dang+1
  521.                                         PutChar(dumb,tmp3);dumb:=dumb+1
  522.                                         z:=Char(linebuf+v)
  523.                                         IF (hammode=FALSE)
  524.                                             tmp1:=red[z];tmp2:=grn[z];tmp3:=blu[z]
  525.                                         ELSE
  526.                                             IF (bmhd.depth=8)    -> HAM8
  527.                                                 speed7:=(z AND %11000000)
  528.                                                 IF (speed7)
  529.                                                     IF (speed7=%10000000)    -> Modify RED
  530.                                                         tmp1:=Shl((z AND %111111),2)
  531.                                                     ELSE
  532.                                                         IF (speed7=%01000000)
  533.                                                             tmp3:=Shl((z AND %111111),2)
  534.                                                         ELSE
  535.                                                             tmp2:=Shl((z AND %111111),2)
  536.                                                         ENDIF
  537.                                                     ENDIF
  538.                                                 ELSE
  539.                                                     speed6:=(z AND %111111)
  540.                                                     tmp1:=red[speed6];tmp2:=grn[speed6];tmp3:=blu[speed6]
  541.                                                 ENDIF
  542.                                             ELSE
  543.                                                 IF (z AND %110000)
  544.                                                     IF (z AND %110000)=%100000    -> Modify RED
  545.                                                         tmp1:=Shl((z AND %1111),4);ENDIF
  546.                                                     IF (z AND %110000)=%010000    -> Modify BLUE
  547.                                                         tmp3:=Shl((z AND %1111),4);ENDIF
  548.                                                     IF (z AND %110000)=%110000    -> Modify GRN
  549.                                                         tmp2:=Shl((z AND %1111),4);ENDIF
  550.                                                 ELSE
  551.                                                     speed6:=(z AND %1111)
  552.                                                     tmp1:=red[speed6];tmp2:=grn[speed6];tmp3:=blu[speed6]
  553.                                                 ENDIF
  554.                                             ENDIF
  555.                                         ENDIF
  556.                                     ENDIF
  557.                                 ENDFOR
  558.                             ENDFOR
  559.                             IF (remap=FALSE)
  560.                                 FOR i:=0 TO speed5
  561.                                     fc:=Char(redbuf+(SpFix(SpMul(xpixper,SpFlt(i)))))
  562.                                     SetAPen(rast,fc)
  563.                                     highpen:=bigger(highpen,fc)
  564.                                      WritePixel(rast,finalx+i,finaly+t)
  565.                                  ENDFOR
  566.                             ELSE
  567.                                 FOR i:=0 TO speed5
  568.                                     tmp4:=(SpFix(SpMul(xpixper,SpFlt(i))))
  569.                                     ditz:=redbuf+tmp4
  570.                                     dang:=grnbuf+tmp4
  571.                                     dumb:=blubuf+tmp4
  572.                                     IF ((sfixy>=1) AND (sfixx>=1))
  573.                                         num:=0;sumred:=0;sumgrn:=0;sumblu:=0
  574.                                         MOVEM.L    D0-D7/A0-A3,-(A7)
  575.                                          MOVE.L    ditz,A0
  576.                                          MOVE.L    dang,A1
  577.                                         MOVE.L    dumb,A2
  578.                                         MOVE.L    bmhd,A3
  579.                                         CLR.L        D2        -> The result from Char()
  580.                                         CLR.L        D4        -> num
  581.                                         CLR.L        D5        -> sumred
  582.                                         CLR.L        D6        -> sumgrn
  583.                                         CLR.L        D7        -> sumblu
  584.                                         MOVE.L    sfixy,D0
  585. ->                                        ADD.L        #1,D0
  586. loop3:
  587.                                         MOVE.L    sfixx,D1
  588. ->                                         ADD.L        #1,D1
  589. loop2:
  590.                                         SUB.L        D3,D3                -> EQ: CLR.L    D3 ? Is it faster??!?
  591.                                         MOVE.W    0(A3),D3
  592.                                         MULU.L    D0,D3
  593.                                         ADD.L        D1,D3
  594.                                         MOVE.B    0(A0,D3),D2
  595.                                         ADD.L        D2,D5
  596.                                         MOVE.B    0(A1,D3),D2
  597.                                         ADD.L        D2,D6
  598.                                         MOVE.B    0(A2,D3),D2
  599.                                         ADD.L        D2,D7
  600.                                         ADDQ.L    #1,D4
  601.                                         DBRA        D1,loop2
  602.                                         DBRA        D0,loop3
  603.                                         MOVE.L    D4,num
  604.                                         MOVE.L    D5,sumred
  605.                                         MOVE.L    D6,sumgrn
  606.                                         MOVE.L    D7,sumblu
  607.                                         MOVEM.L    (A7)+,D0-D7/A0-A3
  608.                                         IF num>0
  609.                                              sumred:=limit(sumred/num,0,255)
  610.                                              sumgrn:=limit(sumgrn/num,0,255)
  611.                                              sumblu:=limit(sumblu/num,0,255)
  612.                                         ENDIF
  613.                                     ELSE
  614.                                          sumred:=Char(ditz)
  615.                                          sumgrn:=Char(dang)
  616.                                          sumblu:=Char(dumb)
  617.                                     ENDIF
  618.                                     MOVE.L    t,D1
  619.                                     MOVE.L    finalw,D2
  620.                                     MULU.L    D2,D1
  621.                                     ADD.L        i,D1
  622.  
  623.                                     MOVE.L    D1,D0
  624.                                     ADD.L        red24,D0
  625.                                     MOVE.L    D0,A0
  626.                                     MOVE.L    sumred,D2
  627.                                     MOVE.B    D2,(A0)
  628.                                     
  629.                                     MOVE.L    D1,D0
  630.                                     ADD.L        grn24,D0
  631.                                     MOVE.L    D0,A0
  632.                                     MOVE.L    sumgrn,D2
  633.                                     MOVE.B    D2,(A0)
  634.                                     
  635.                                     MOVE.L    D1,D0
  636.                                     ADD.L        blu24,D0
  637.                                     MOVE.L    D0,A0
  638.                                     MOVE.L    sumblu,D2
  639.                                     MOVE.B    D2,(A0)
  640.                                     
  641.                                 ENDFOR
  642.                             ENDIF
  643.                         ENDFOR
  644.                         IF grey
  645.                             tmp1:=red24
  646.                             tmp2:=grn24
  647.                             tmp3:=blu24
  648.                             tmp7:=finalh*finalw-1
  649.                             FOR i:=0 TO tmp7
  650.                                 IF grey=1
  651.                                     er1:=(Char(tmp1)*1000)/30
  652.                                     er2:=(Char(tmp2)*1000)/30
  653.                                     er3:=(Char(tmp3)*1000)/30
  654.                                 ELSE
  655.                                     er1:=(Char(tmp1)*3000)/100
  656.                                     er2:=(Char(tmp2)*6000)/100
  657.                                     er3:=(Char(tmp3)*1000)/100
  658.                                 ENDIF
  659.                                 er4:=(er1+er2+er3)/100
  660.                                 PutChar(tmp1,er4)
  661.                                 PutChar(tmp2,er4)
  662.                                 PutChar(tmp3,er4)
  663.                                 tmp1:=tmp1+1
  664.                                 tmp2:=tmp2+1
  665.                                 tmp3:=tmp3+1
  666.                             ENDFOR
  667.                         ENDIF
  668.  
  669.                         IF (fillcmap)
  670.                             IF usehighpen>=quant THEN usehighpen:=(quant-1)
  671.                             SELECT quantmode
  672.                             CASE QUANT_VERBATIM
  673.                                 FOR i:=0 TO quant
  674.                                     SetRGB32CM(cmap,smaller(i,255),byte2long(red[i]),byte2long(grn[i]),byte2long(blu[i]))
  675.                                 ENDFOR
  676.                             CASE QUANT_POPULARITY
  677.                                 histo:=New(20000)
  678.                                 FOR t:=0 TO finalh-1
  679.                                     IF checkcancel(statwindow) THEN Raise("canc")
  680.                                     IF (((t+3)/4)=(t/4))
  681.                                         IF statgauge THEN fuelgauge(statgauge,t,finalh-1,stat.histogram_string)
  682.                                     ENDIF
  683.                                     FOR i:=0 TO finalw-1
  684.                                         tmp1:=Shr((Char(red24+(t*finalw)+i) AND $F0) ,4)
  685.                                         tmp2:=Shr((Char(grn24+(t*finalw)+i) AND $F0) ,4)
  686.                                         tmp3:=Shr((Char(blu24+(t*finalw)+i) AND $F0) ,4)
  687.                                         tmp4:=histo+((tmp1+(tmp2*16)+(tmp3*256))*4)
  688.                                         PutLong(tmp4,(Long(tmp4)+1))
  689.                                     ENDFOR
  690.                                 ENDFOR
  691.                                 FOR i:=0 TO quant
  692.                                     IF checkcancel(statwindow) THEN Raise("canc")
  693.                                     IF (((i+3)/4)=(i/4))
  694.                                         IF statgauge THEN fuelgauge(statgauge,i,quant,stat.quant_string)
  695.                                     ENDIF
  696.                                     tmp1:=0
  697.                                     tmp2:=0
  698.                                     tmp3:=histo
  699.                                     FOR t:=0 TO 4095
  700.                                         IF Long(tmp3)>tmp2
  701.                                             tmp2:=Long(tmp3)
  702.                                             tmp1:=t
  703.                                         ENDIF
  704.                                         tmp3:=tmp3+4
  705.                                     ENDFOR
  706.                                     PutLong(histo+(tmp1*4),0)
  707.                                     er1:=tmp1 AND $F
  708.                                     er1:=er1 OR Shl(er1,4)
  709.                                     er2:=Shr((tmp1 AND $F0),4)
  710.                                     er2:=er2 OR Shl(er2,4)
  711.                                     er3:=Shr((tmp1 AND $F00),8)
  712.                                     er3:=er3 OR Shl(er3,4)
  713.                                     SetRGB32CM(cmap,smaller(i,255),byte2long(er1),byte2long(er2),byte2long(er3))
  714.                                 ENDFOR
  715.                             CASE QUANT_MEDIANCUT
  716.                                 cm:=domediancut(red24,grn24,blu24,finalw,finalh,cmap,quant)
  717.                                 IF (cm)
  718.                                     FOR i:=0 TO (quant)
  719.                                         SetRGB32CM(cmap,smaller(i,255),byte2long(PPM_GETR(Long(cm+(i*SIZEOF colorhist_item)))),byte2long(PPM_GETG(Long(cm+(i*SIZEOF colorhist_item)))),byte2long(PPM_GETB(Long(cm+(i*SIZEOF colorhist_item)))))
  720.                                     ENDFOR
  721.                                     Dispose(cm)
  722.                                 ENDIF
  723.                             ENDSELECT
  724.                             doexchange(cmap,3,0,255,255,usehighpen)
  725.                             doexchange(cmap,2,255,255,255,usehighpen)
  726.                             doexchange(cmap,1,0,0,0,usehighpen)
  727.                             doexchange(cmap,0,128,128,128,usehighpen)
  728.                         ENDIF
  729.                         IF (norender) THEN Raise("nore")
  730.                         IF (clear<>FALSE);SetAPen(rast,0);RectFill(rast,x,y,x+w-1,y+h-1);ENDIF
  731.                         FOR i:=0 TO Shl(1,8)-1
  732.                             GetRGB32(cmap,i,1,grabbuf)
  733.                             realred[i]:=Char(grabbuf)
  734.                             realgrn[i]:=Char(grabbuf+4)
  735.                             realblu[i]:=Char(grabbuf+8)
  736.                         ENDFOR
  737.                         IF renderham THEN dither:=FALSE
  738.                         FOR t:=0 TO finalh-1
  739.                             IF checkcancel(statwindow) THEN Raise("canc")
  740.                             IF (((t+3)/4)=(t/4))
  741.                                 IF ((gauge<>0) AND (drawinfo<>0))
  742.                                     IF (gauge.rast<>0)
  743.                                         SetAPen(gauge.rast,Int(drawinfo.pens+(FILLPEN*2)))
  744.                                         RectFill(gauge.rast,gauge.x,gauge.y,gauge.x+((((gauge.w-2)*100)/(10000/(bigger((t*100/(finalh-1)),1))))),gauge.y+gauge.h-1)
  745.                                     ENDIF
  746.                                 ENDIF
  747.                                 IF (gaugestr<>0)
  748.                                     WriteF(gaugestr,smaller(((t*100))/(bigger(finalh-1,1)),100))
  749.                                 ENDIF
  750.                                 IF statgauge THEN fuelgauge(statgauge,t,finalh-1,stat.render_string)
  751.                             ENDIF
  752.  
  753.                             IF ((((t+1)/2)=(t/2)) OR (renderham>5) OR (dithermode=DITH_ERRORDIFF))
  754.                                 i:=0;stop:=finalw;step:=1
  755.                                 tmp4:=t*finalw
  756.                                 tmp1:=red24+tmp4
  757.                                 tmp2:=grn24+tmp4
  758.                                 tmp3:=blu24+tmp4
  759.                             ELSE
  760.                                 i:=finalw-1;stop:=-1;step:=-1
  761.                                 tmp4:=(t*finalw)+(finalw-1)
  762.                                 tmp1:=red24+tmp4
  763.                                 tmp2:=grn24+tmp4
  764.                                 tmp3:=blu24+tmp4
  765.                             ENDIF
  766.                             REPEAT
  767.                                 tmp4:=Char(tmp1)
  768.                                 tmp5:=Char(tmp2)
  769.                                 tmp6:=Char(tmp3)
  770.                                 lmp4:=byte2long(tmp4)
  771.                                 lmp5:=byte2long(tmp5)
  772.                                 lmp6:=byte2long(tmp6)
  773.                                 IF (dither=FALSE)
  774.                                     SELECT 9 OF renderham
  775.                                     CASE 6,8
  776.                                         IF (i>0)
  777.                                             fc:=FindColor(cmap,lmp4,lmp5,lmp6,hambase)
  778.                                             hadr:=Abs(tmp4-realred[fc])
  779.                                             hadg:=Abs(tmp5-realgrn[fc])
  780.                                             hadb:=Abs(tmp6-realblu[fc])
  781.                                             IF ((hadr+hadg+hadb)<=hamthres)
  782.                                                 hamr:=realred[fc]            -> CHAR
  783.                                                 hamg:=realgrn[fc]
  784.                                                 hamb:=realblu[fc]
  785.                                             ELSE
  786.                                                 hadr:=Abs(tmp4-hamr)    -> CHAR-CHAR
  787.                                                 hadg:=Abs(tmp5-hamg)
  788.                                                 hadb:=Abs(tmp6-hamb)
  789.                                                 IF (renderham=8)
  790.                                                     IF ((hadb>(hadr*2)) AND (hadb>(hadg*3)))
  791.                                                         hamb:=(tmp6 AND %11111100)
  792.                                                         fc:=(%01000000 OR Shr(hamb,2))
  793.                                                         IF (discard) THEN hamb:=(tmp6 AND %11111111)
  794.                                                     ELSE
  795.                                                         IF (hadr>(hadg*2))
  796.                                                             hamr:=(tmp4 AND %11111100)
  797.                                                             fc:=(%10000000 OR Shr(hamr,2))
  798.                                                             IF (discard) THEN hamr:=(tmp4 AND %11111111)
  799.                                                         ELSE
  800.                                                             hamg:=(tmp5 AND %11111100)
  801.                                                             fc:=(%11000000 OR Shr(hamg,2))
  802.                                                             IF (discard) THEN hamg:=(tmp5 AND %11111111)
  803.                                                         ENDIF
  804.                                                     ENDIF
  805.                                                 ELSE
  806.                                                     IF ((hadb>(hadr*2)) AND (hadb>(hadg*3)))
  807.                                                         hamb:=(tmp6 AND %11110000)
  808.                                                         fc:=(%010000 OR Shr(hamb,4))
  809.                                                         IF (discard) THEN hamb:=(tmp6 AND %11111111)
  810.                                                     ELSE
  811.                                                         IF (hadr>(hadg*2))
  812.                                                             hamr:=(tmp4 AND %11110000)
  813.                                                             fc:=(%100000 OR Shr(hamr,4))
  814.                                                             IF (discard) THEN hamr:=(tmp4 AND %11111111)
  815.                                                         ELSE
  816.                                                             hamg:=(tmp5 AND %11110000)
  817.                                                             fc:=(%110000 OR Shr(hamg,4))
  818.                                                             IF (discard) THEN hamg:=(tmp5 AND %11111111)
  819.                                                         ENDIF
  820.                                                     ENDIF
  821.                                                 ENDIF
  822.                                             ENDIF
  823.                                         ELSE
  824.                                             fc:=FindColor(cmap,lmp4,lmp5,lmp6,hambase)
  825.                                             hamr:=realred[fc]
  826.                                             hamg:=realgrn[fc]
  827.                                             hamb:=realblu[fc]
  828.                                         ENDIF
  829.                                     DEFAULT
  830.                                         fc:=FindColor(cmap,lmp4,lmp5,lmp6,usehighpen)
  831.                                     ENDSELECT
  832.                                     IF fc>highpen THEN highpen:=fc
  833.                                     SetAPen(rast,fc)
  834.                                     WritePixel(rast,finalx+i,finaly+t)
  835.                                 ELSE                                                                                -> Do dither!
  836.                                     fc:=FindColor(cmap,lmp4,lmp5,lmp6,usehighpen)
  837.                                     IF fc>highpen THEN highpen:=fc
  838.                                     SetAPen(rast,fc)
  839.                                     WritePixel(rast,finalx+i,finaly+t)
  840.                          reddif:=tmp4-realred[fc]
  841.                        grndif:=tmp5-realgrn[fc]
  842.                        bludif:=tmp6-realblu[fc]
  843.                        SELECT 4 OF dithermode
  844.                        CASE DITH_FLOYD,DITH_ERRORDIFF
  845.                            IF dithermode=DITH_FLOYD
  846.                                er1:=(reddif*7)/16
  847.                                er2:=(reddif*3)/16
  848.                                er3:=(reddif*5)/16
  849.                                er4:=reddif-er1-er2-er3
  850.                                eg1:=(grndif*7)/16
  851.                                eg2:=(grndif*3)/16
  852.                                eg3:=(grndif*5)/16
  853.                                eg4:=grndif-eg1-eg2-eg3
  854.                                eb1:=(bludif*7)/16
  855.                                eb2:=(bludif*3)/16
  856.                                eb3:=(bludif*5)/16
  857.                                eb4:=bludif-eb1-eb2-eb3
  858.                            ELSE
  859.                                er1:=(reddif*3)/8 AND %11111111111111111111111111111110
  860.                                er2:=0
  861.                                er3:=er1
  862.                                er4:=reddif-er1-er3 AND %11111111111111111111111111111100
  863.                                eg1:=(grndif*3)/8 AND %11111111111111111111111111111100
  864.                                eg2:=0
  865.                                eg3:=eg1
  866.                                eg4:=grndif-eg1-eg3 AND %11111111111111111111111111111100
  867.                                eb1:=(bludif*3)/8 AND  %11111111111111111111111111111110
  868.                                eb2:=0
  869.                                eb3:=eb1
  870.                                eb4:=bludif-eb1-eb3 AND %11111111111111111111111111111100
  871.                              ENDIF
  872.                            IF step=1
  873.                                IF ((i+1)<stop)
  874.                                                 byteplace(tmp1+1,er1)
  875.                                                 byteplace(tmp2+1,eg1)
  876.                                                 byteplace(tmp3+1,eb1)
  877.                                             ENDIF
  878.                                IF t<(finalh-1)
  879.                                      IF ((i+1)<stop)
  880.                                          byteplace(tmp1+1+finalw,er4)
  881.                                          byteplace(tmp2+1+finalw,eg4)
  882.                                          byteplace(tmp3+1+finalw,eb4)
  883.                                      ENDIF
  884.                                      IF (i>0)
  885.                                                     byteplace(tmp1-1+finalw,er2)
  886.                                                     byteplace(tmp2-1+finalw,eg2)
  887.                                                     byteplace(tmp3-1+finalw,eb2)
  888.                                                 ENDIF
  889.                                      byteplace(tmp1+finalw,er3)
  890.                                      byteplace(tmp2+finalw,eg3)
  891.                                      byteplace(tmp3+finalw,eb3)
  892.                                  ENDIF
  893.                            ELSE
  894.                                IF ((i-1)>stop)
  895.                                    byteplace(tmp1-1,er1)
  896.                                    byteplace(tmp2-1,eg1)
  897.                                    byteplace(tmp3-1,eb1)
  898.                                ENDIF
  899.                                IF t<(finalh-1)
  900.                                      IF ((i-1)>stop)
  901.                                          byteplace(tmp1-1+finalw,er4)
  902.                                          byteplace(tmp2-1+finalw,eg4)
  903.                                          byteplace(tmp3-1+finalw,eb4)
  904.                                      ENDIF
  905.                                      IF (i<(finalw-1))
  906.                                          byteplace(tmp1+1+finalw,er2)
  907.                                          byteplace(tmp2+1+finalw,eg2)
  908.                                          byteplace(tmp3+1+finalw,eb2)
  909.                                      ENDIF
  910.                                      byteplace(tmp1+finalw,er3)
  911.                                      byteplace(tmp2+finalw,eg3)
  912.                                      byteplace(tmp3+finalw,eb3)
  913.                                  ENDIF
  914.                            ENDIF
  915.                        CASE DITH_BURKES,DITH_STUCKI
  916.                            IF dithermode=DITH_BURKES
  917.                                er1:=(reddif*8)/32                                ->8
  918.                                er2:=(reddif*4)/32                                ->4
  919.                                er3:=(reddif-(er1*2)-(er2*3))/2        ->2
  920.                                eg1:=(grndif*8)/32
  921.                                eg2:=(grndif*4)/32
  922.                                eg3:=(grndif-(eg1*2)-(eg2*3))/2
  923.                                eb1:=(bludif*8)/32
  924.                                eb2:=(bludif*4)/32
  925.                                eb3:=(bludif-(eb1*2)-(eb2*3))/2
  926.                              ELSE
  927.                                er1:=(reddif*8)/42                                ->8
  928.                                er2:=(reddif*4)/42                                ->4
  929.                                er3:=(reddif*2)/42                                ->2
  930.                                er4:=(reddif-(er1*2)-(er2*4)-(er3*4))/2        ->1
  931.                                eg1:=(grndif*8)/42
  932.                                eg2:=(grndif*4)/42
  933.                                eg3:=(grndif*2)/42
  934.                                eg4:=(grndif-(eg1*2)-(eg2*4)-(eg3*4))/2
  935.                                eb1:=(bludif*8)/42
  936.                                eb2:=(bludif*4)/42
  937.                                eb3:=(bludif*2)/42
  938.                                eb4:=(bludif-(eb1*2)-(eb2*4)-(eb3*4))/2
  939.                              ENDIF
  940.                            IF step=1
  941.                                IF ((i+1)<stop)
  942.                                                 byteplace(tmp1+1,er1)
  943.                                                 byteplace(tmp2+1,eg1)
  944.                                                 byteplace(tmp3+1,eb1)
  945.                                                 IF ((i+2)<stop)
  946.                                                     byteplace(tmp1+2,er2)
  947.                                                     byteplace(tmp2+2,eg2)
  948.                                                     byteplace(tmp3+2,eb2)
  949.                                                 ENDIF
  950.                                             ENDIF
  951.                                IF t<(finalh-1)
  952.                                    ttmp1:=tmp1+finalw
  953.                                    ttmp2:=tmp2+finalw
  954.                                    ttmp3:=tmp3+finalw
  955.                                      IF ((i+1)<stop)
  956.                                          byteplace(ttmp1+1,er2)
  957.                                          byteplace(ttmp2+1,eg2)
  958.                                          byteplace(ttmp3+1,eb2)
  959.                                                     IF ((i+2)<stop)
  960.                                                         byteplace(ttmp1+2,er3)
  961.                                                         byteplace(ttmp2+2,eg3)
  962.                                                         byteplace(ttmp3+2,eb3)
  963.                                                     ENDIF
  964.                                      ENDIF
  965.                                      IF (i>0)
  966.                                                     byteplace(ttmp1-1,er2)
  967.                                                     byteplace(ttmp2-1,eg2)
  968.                                                     byteplace(ttmp3-1,eb2)
  969.                                          IF (i>1)
  970.                                                         byteplace(ttmp1-2,er3)
  971.                                                         byteplace(ttmp2-2,eg3)
  972.                                                         byteplace(ttmp3-2,eb3)
  973.                                          ENDIF
  974.                                                 ENDIF
  975.                                      byteplace(ttmp1,er1)
  976.                                      byteplace(ttmp2,eg1)
  977.                                      byteplace(ttmp3,eb1)
  978.                                      IF dithermode=DITH_STUCKI
  979.                                        IF t<(finalh-1)
  980.                                            ttmp1:=ttmp1+finalw
  981.                                            ttmp2:=ttmp2+finalw
  982.                                            ttmp3:=ttmp3+finalw
  983.                                              IF ((i+1)<stop)
  984.                                                  byteplace(ttmp1+1,er3)
  985.                                                  byteplace(ttmp2+1,eg3)
  986.                                                  byteplace(ttmp3+1,eb3)
  987.                                                             IF ((i+2)<stop)
  988.                                                                 byteplace(ttmp1+2,er4)
  989.                                                                 byteplace(ttmp2+2,eg4)
  990.                                                                 byteplace(ttmp3+2,eb4)
  991.                                                             ENDIF
  992.                                              ENDIF
  993.                                              IF (i>0)
  994.                                                             byteplace(ttmp1-1,er3)
  995.                                                             byteplace(ttmp2-1,eg3)
  996.                                                             byteplace(ttmp3-1,eb3)
  997.                                                  IF (i>1)
  998.                                                                 byteplace(ttmp1-2,er4)
  999.                                                                 byteplace(ttmp2-2,eg4)
  1000.                                                                 byteplace(ttmp3-2,eb4)
  1001.                                                  ENDIF
  1002.                                                         ENDIF
  1003.                                              byteplace(ttmp1,er2)
  1004.                                              byteplace(ttmp2,eg2)
  1005.                                              byteplace(ttmp3,eb2)
  1006.                                          ENDIF
  1007.                                      ENDIF
  1008.                                  ENDIF
  1009.                            ELSE
  1010.                                IF ((i-1)>stop)
  1011.                                                 byteplace(tmp1-1,er1)
  1012.                                                 byteplace(tmp2-1,eg1)
  1013.                                                 byteplace(tmp3-1,eb1)
  1014.                                                 IF ((i-2)>stop)
  1015.                                                     byteplace(tmp1-2,er2)
  1016.                                                     byteplace(tmp2-2,eg2)
  1017.                                                     byteplace(tmp3-2,eb2)
  1018.                                                 ENDIF
  1019.                                             ENDIF
  1020.                                IF t<(finalh-1)
  1021.                                    ttmp1:=tmp1+finalw
  1022.                                    ttmp2:=tmp2+finalw
  1023.                                    ttmp3:=tmp3+finalw
  1024.                                      IF ((i-1)>stop)
  1025.                                          byteplace(ttmp1-1,er2)
  1026.                                          byteplace(ttmp2-1,eg2)
  1027.                                          byteplace(ttmp3-1,eb2)
  1028.                                                     IF ((i-2)>stop)
  1029.                                                         byteplace(ttmp1-2,er3)
  1030.                                                         byteplace(ttmp2-2,eg3)
  1031.                                                         byteplace(ttmp3-2,eb3)
  1032.                                                     ENDIF
  1033.                                      ENDIF
  1034.                                      IF (i<(finalw-1))
  1035.                                                     byteplace(ttmp1+1,er2)
  1036.                                                     byteplace(ttmp2+1,eg2)
  1037.                                                     byteplace(ttmp3+1,eb2)
  1038.                                          IF (i<(finalw-2))
  1039.                                                         byteplace(ttmp1+2,er3)
  1040.                                                         byteplace(ttmp2+2,eg3)
  1041.                                                         byteplace(ttmp3+2,eb3)
  1042.                                          ENDIF
  1043.                                                 ENDIF
  1044.                                      byteplace(ttmp1,er1)
  1045.                                      byteplace(ttmp2,eg1)
  1046.                                      byteplace(ttmp3,eb1)
  1047.                                      IF dithermode=DITH_STUCKI
  1048.                                        IF (t<(finalh-1))
  1049.                                            ttmp1:=ttmp1+finalw
  1050.                                            ttmp2:=ttmp2+finalw
  1051.                                            ttmp3:=ttmp3+finalw
  1052.                                              IF ((i-1)>stop)
  1053.                                                  byteplace(ttmp1-1,er3)
  1054.                                                  byteplace(ttmp2-1,eg3)
  1055.                                                  byteplace(ttmp3-1,eb3)
  1056.                                                             IF ((i-2)>stop)
  1057.                                                                 byteplace(ttmp1-2,er4)
  1058.                                                                 byteplace(ttmp2-2,eg4)
  1059.                                                                 byteplace(ttmp3-2,eb4)
  1060.                                                             ENDIF
  1061.                                              ENDIF
  1062.                                              IF (i<(finalw-1))
  1063.                                                             byteplace(ttmp1+1,er3)
  1064.                                                             byteplace(ttmp2+1,eg3)
  1065.                                                             byteplace(ttmp3+1,eb3)
  1066.                                                  IF (i<(finalw-2))
  1067.                                                                 byteplace(ttmp1+2,er4)
  1068.                                                                 byteplace(ttmp2+2,eg4)
  1069.                                                                 byteplace(ttmp3+2,eb4)
  1070.                                                  ENDIF
  1071.                                                         ENDIF
  1072.                                              byteplace(ttmp1,er2)
  1073.                                              byteplace(ttmp2,eg2)
  1074.                                              byteplace(ttmp3,eb2)
  1075.                                          ENDIF
  1076.                                      ENDIF
  1077.                                  ENDIF
  1078.                            ENDIF
  1079.                                     ENDSELECT
  1080.                                 ENDIF
  1081.                                 tmp1:=tmp1+step
  1082.                                 tmp2:=tmp2+step
  1083.                                 tmp3:=tmp3+step
  1084.                             i:=i+step;UNTIL i=stop
  1085.                         ENDFOR
  1086.                     ENDIF
  1087.                     IF (renderham=6) THEN highpen:=63
  1088.                     IF (renderham=8) THEN highpen:=255
  1089.                     IF iinfo
  1090.                         iinfo.source_w:=bmhd.width
  1091.                         iinfo.source_h:=bmhd.height
  1092.                         iinfo.destination_x:=finalx
  1093.                         iinfo.destination_y:=finaly
  1094.                         iinfo.destination_w:=finalw
  1095.                         iinfo.destination_h:=finalh
  1096.                         iinfo.depth:=bmhd.depth
  1097.                         iinfo.highest_pen:=highpen
  1098.                         IF ((renderham=6) OR (renderham=8)) THEN usehighpen:=3
  1099.                         iinfo.blackpen:=FindColor(cmap,0,0,0,usehighpen)
  1100.                         iinfo.whitepen:=FindColor(cmap,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,usehighpen)
  1101.                         iinfo.greypen:=FindColor(cmap,$99999999,$99999999,$99999999,usehighpen)
  1102.                         IF statwindow
  1103.                             iinfo.statwindowx:=stat.centerx-(statx-statwindow.leftedge)
  1104.                             iinfo.statwindowy:=stat.centery-(staty-statwindow.topedge)
  1105.                         ENDIF
  1106.                     ENDIF
  1107.                     IF (gaugestr<>0)
  1108.                         WriteF(gaugestr,100)
  1109.                     ENDIF
  1110.                 ELSE
  1111.                     Raise("MEM")
  1112.                 ENDIF
  1113.             ELSE
  1114.                 Raise("Nodt")
  1115.             ENDIF
  1116.         ELSE
  1117.             Raise("Nodt")
  1118.         ENDIF
  1119.     ELSE
  1120.         Raise("Nodt")
  1121.     ENDIF
  1122. EXCEPT DO
  1123.     res:=exception
  1124.     IF statwindow
  1125.         CloseWindow(statwindow)
  1126.         IF glist
  1127.             FreeGadgets(glist)
  1128.         ENDIF
  1129.         statwindow:=0
  1130.     ENDIF
  1131.     IF statgauge THEN endgauge(statgauge)
  1132.     IF drawinfo THEN FreeScreenDrawInfo(gauge.scr,drawinfo)
  1133.     IF vis THEN FreeVisualInfo(vis)
  1134.     IF obj THEN DisposeDTObject(obj)
  1135.     IF tbm THEN FreeBitMap(tbm)
  1136.     IF redbuf THEN Dispose(redbuf)
  1137.     IF grnbuf THEN Dispose(grnbuf)
  1138.     IF blubuf THEN Dispose(blubuf)
  1139.     IF linebuf THEN Dispose(linebuf)
  1140.     IF trast THEN Dispose(trast)
  1141.     IF dtf THEN Dispose(dtf)
  1142.     IF fri THEN Dispose(fri)
  1143.     IF histo THEN Dispose(histo)
  1144.     IF red24 THEN Dispose(red24)
  1145.     IF grn24 THEN Dispose(grn24)
  1146.     IF blu24 THEN Dispose(blu24)
  1147.     IF gpl THEN Dispose(gpl)
  1148.     IF dtrast THEN Dispose(dtrast)
  1149.     ->WriteF('\n End AVAILMEM-\d\n',AvailMem(MEMF_ANY))
  1150. ENDPROC res
  1151.  
  1152. PROC checklibs()
  1153.     IF ((iffparsebase) AND (utilitybase) AND (datatypesbase) AND (mathbase)) THEN RETURN TRUE
  1154. ENDPROC FALSE        
  1155.  
  1156. PROC checkcancel(window:PTR TO window)
  1157.     DEF mes:PTR TO intuimessage
  1158.     DEF    class
  1159.     DEF retu=FALSE
  1160.     IF window
  1161.         REPEAT
  1162.             IF mes:=Gt_GetIMsg(window.userport)
  1163.                 class:=extractmessage(mes)
  1164.                 IF (class=IDCMP_GADGETUP)
  1165.                     retu:=TRUE
  1166.                 ELSEIF class=IDCMP_REFRESHWINDOW
  1167.                     Gt_BeginRefresh(window)
  1168.                     Gt_EndRefresh(window,TRUE)
  1169.                 ENDIF
  1170.                 Gt_ReplyIMsg(mes)
  1171.             ENDIF
  1172.         UNTIL mes=0
  1173.     ELSE
  1174.         IF CtrlC() THEN retu:=TRUE
  1175.     ENDIF
  1176. ENDPROC retu
  1177.  
  1178. PROC byteplace(loc,error)
  1179.     DEF old
  1180.     old:=Char(loc)
  1181.     old:=old+error
  1182.     IF old<0 THEN old:=0
  1183.     IF old>255 THEN old:=255
  1184.     PutChar(loc,old)
  1185. ENDPROC
  1186.  
  1187. PROC rgbint(intval)
  1188.     DEF r,g,b
  1189.     r:=intval AND $F
  1190.     r:=r OR Shl(r,4)
  1191.     g:=Shr((intval AND $F0),4)
  1192.     g:=g OR Shl(g,4)
  1193.     b:=Shr((intval AND $F00),8)
  1194.     b:=b OR Shl(b,4)
  1195. ENDPROC r,g,b
  1196.  
  1197. PROC rgb2int(r,g,b)
  1198.     DEF int=0
  1199.     int:=(Shr(r,4) OR (Shl(Shr(g,4),4)) OR (Shl(Shr(b,4),8)) )
  1200. ENDPROC int
  1201.  
  1202. PROC rgbtab(r,g,b)
  1203.     DEF rr
  1204.     rr:=(r+(g*16)+(b*256))*4
  1205. ENDPROC rr
  1206.  
  1207. PROC domediancut(redbuf,grnbuf,blubuf,width,height,palette,newcolors)
  1208.     DEF chv=0:PTR TO colorhist_item
  1209.     DEF colors=0
  1210.     DEF colormap
  1211.     
  1212.     histopool:=createpool()
  1213.     chv:=computecolorhist(redbuf,grnbuf,blubuf,width,height,MAXCOLORS,{colors})
  1214.     IF chv
  1215. ->        WriteF('\n\nFOUND \d COLORS! -- Choosing \d colors...\n\n',colors,newcolors)
  1216.  
  1217.         colormap:=mediancut(chv,colors,width*height,newcolors)
  1218.         
  1219.         Dispose(chv)
  1220.     ENDIF
  1221. ENDPROC colormap
  1222.  
  1223. PROC mediancut(chv,colors,sum,newcolors)
  1224.     DEF colormap=0,bv=0
  1225.     DEF boxes,bi,i,bigbox,movebox,tmp1,tmp2,score
  1226.     DEF box:PTR TO box,chi:PTR TO colorhist_item
  1227.     DEF indx,clrs,sm,minr,maxr,ming,maxg,minb,maxb,v,halfsum,lowersum
  1228.     DEF r,g,b
  1229.     DEF rl,gl,bl
  1230.     DEF f_0_299,f_0_587,f_0_114
  1231.     DEF colo
  1232.     bv:=New((SIZEOF box*newcolors)+100)
  1233.     f_0_299:=SpDiv(SpFlt(1000),SpFlt(299))
  1234.     f_0_587:=SpDiv(SpFlt(1000),SpFlt(587))
  1235.     f_0_114:=SpDiv(SpFlt(1000),SpFlt(114))
  1236.     IF (bv)
  1237.         colormap:=New((SIZEOF colorhist_item*newcolors)+100)
  1238.         IF (colormap)
  1239.             FOR i:=0 TO (newcolors-1)
  1240.                 PutLong(colormap+(i*SIZEOF colorhist_item),0)
  1241.                 PutLong(colormap+(i*SIZEOF colorhist_item)+4,0)
  1242.             ENDFOR
  1243.             box:=bv
  1244.             box.ind:=0
  1245.             box.colors:=colors
  1246.             box.sum:=sum
  1247.             boxes:=1
  1248.             sizebox(box,chv)
  1249.             WHILE (boxes<newcolors)
  1250.  
  1251.                 IF checkcancel(statwindow)
  1252.                     IF chv THEN Dispose(chv)
  1253.                     IF bv THEN Dispose(bv)
  1254.                     IF colormap THEN Dispose(colormap)
  1255.                     Raise("canc")
  1256.                 ENDIF
  1257.                 IF (((boxes+1)/2)<>(boxes/2))
  1258.                     IF statgauge THEN fuelgauge(statgauge,boxes,newcolors,stat.quant_string)
  1259.                 ENDIF
  1260.  
  1261.                 FOR bi:=0 TO (boxes-1)
  1262.                     box:=bv+(bi*SIZEOF box)
  1263.                     IF box.colors>=2 THEN JUMP break2
  1264.                 ENDFOR
  1265.                 JUMP break3
  1266. break2:
  1267. ->                IF (bi=boxes) THEN JUMP break3
  1268.                 indx:=box.ind
  1269.                 clrs:=box.colors
  1270.                 sm:=box.sum
  1271.                 
  1272.                 rl:=SpMul(SpFlt(box.redw),f_0_299)
  1273.                 gl:=SpMul(SpFlt(box.grnw),f_0_587)
  1274.                 bl:=SpMul(SpFlt(box.bluw),f_0_114)
  1275.                 rl:=SpFlt(box.redw)
  1276.                 gl:=SpFlt(box.grnw)
  1277.                 bl:=SpFlt(box.bluw)
  1278. /*                rl:=SpMul(SpFlt(box.bluw),f_0_299)
  1279.                 gl:=SpMul(SpFlt(box.grnw),f_0_587)
  1280.                 bl:=SpMul(SpFlt(box.bluw),f_0_114)
  1281.                 chi:=chv+(indx*SIZEOF colorhist_item)
  1282.                 colo:=chi.color
  1283.                 minr:=PPM_GETR(colo);maxr:=minr
  1284.                 ming:=PPM_GETG(colo);maxg:=ming
  1285.                 minb:=PPM_GETB(colo);maxb:=minb
  1286.                 FOR i:=1 TO (clrs-1)
  1287.                     chi:=chv+((indx+i)*SIZEOF colorhist_item)
  1288.                     colo:=chi.color
  1289.                     v:=PPM_GETR(colo)
  1290.                     IF (v<minr) THEN minr:=v
  1291.                     IF (v>maxr) THEN maxr:=v
  1292.                     v:=PPM_GETG(colo)
  1293.                     IF (v<ming) THEN ming:=v
  1294.                     IF (v>maxg) THEN maxg:=v
  1295.                     v:=PPM_GETB(colo)
  1296.                     IF (v<minb) THEN minb:=v
  1297.                     IF (v>maxb) THEN maxb:=v
  1298.                 ENDFOR
  1299.                 rl:=SpMul(SpFlt(maxr-minr),f_0_299)
  1300.                 gl:=SpMul(SpFlt(maxg-ming),f_0_587)
  1301.                 bl:=SpMul(SpFlt(maxb-minb),f_0_114)*/
  1302.                 IF ((SpCmp(rl,gl)>0) AND (SpCmp(rl,bl)>0))
  1303.                     qsort(chv+(indx*SIZEOF colorhist_item),0,clrs-1,$FF0000)
  1304. /*
  1305. WriteF('\n------------RED--------------')
  1306. FOR i:=0 TO clrs-1
  1307.     chi:=chv+((i+indx)*SIZEOF colorhist_item)
  1308.     WriteF('\n\h[8] \d[6]',chi.color,chi.value)
  1309. ENDFOR
  1310. */
  1311.                 ELSE
  1312.                     IF (SpCmp(gl,bl)>0)
  1313.                         qsort(chv+(indx*SIZEOF colorhist_item),0,clrs-1,$FF00)
  1314. /*
  1315. WriteF('\n------------GRN--------------')
  1316. FOR i:=0 TO clrs-1
  1317.     chi:=chv+((i+indx)*SIZEOF colorhist_item)
  1318.     WriteF('\n\h[8] \d[6]',chi.color,chi.value)
  1319. ENDFOR
  1320. */
  1321.                     ELSE
  1322.                         qsort(chv+(indx*SIZEOF colorhist_item),0,clrs-1,$FF)
  1323. /*
  1324. WriteF('\n------------BLU--------------')
  1325. FOR i:=0 TO clrs-1
  1326.     chi:=chv+((i+indx)*SIZEOF colorhist_item)
  1327.     WriteF('\n\h[8] \d[6]',chi.color,chi.value)
  1328. ENDFOR
  1329. */
  1330.                     ENDIF
  1331.                 ENDIF
  1332.                 chi:=chv+(indx*SIZEOF colorhist_item)
  1333.                 lowersum:=chi.value
  1334.                 halfsum:=(sm/2)
  1335. ->WriteF('\n\d,',lowersum)
  1336.                 i:=1
  1337.                 WHILE (i<(clrs-1))
  1338.                     IF (lowersum>=halfsum) THEN JUMP break4
  1339.                     chi:=chv+((indx+i)*SIZEOF colorhist_item)
  1340.                     lowersum:=lowersum+(chi.value)
  1341. ->WriteF('\d,',lowersum)
  1342.                 i:=i+1;ENDWHILE
  1343.  
  1344. break4:
  1345.                 lowersum:=limit(lowersum,0,sm-1)
  1346.                 box:=bv+(bi*SIZEOF box)
  1347.                 box.colors:=i
  1348.                 box.sum:=lowersum
  1349.                 sizebox(box,chv)
  1350.                 box:=bv+(boxes*SIZEOF box)
  1351.                 box.ind:=indx+i
  1352.                 box.colors:=clrs-i
  1353.                 box.sum:=sm-lowersum
  1354.                 sizebox(box,chv)
  1355.                 boxes:=boxes+1
  1356.  
  1357. /*                IF (box.sum<=0)
  1358.                     WriteF('\nSMALL SUM=\d \d \d',box.sum,sm,lowersum)
  1359.                 ENDIF*/
  1360.  
  1361.                 bigbox:=0;movebox:=0
  1362.                 box:=bv
  1363.                 FOR i:=1 TO boxes-1
  1364.                     box:=(box+SIZEOF box)
  1365.                     IF (box.colors>1)
  1366.                         score:=(((box.redw*box.redw))+((box.grnw*box.grnw))+(box.bluw*box.bluw))
  1367. ->*(box.sum)            
  1368.                         IF score>bigbox;movebox:=i;bigbox:=score;ENDIF
  1369. /*
  1370.                         IF box.redw>bigbox;bigbox:=box.redw;movebox:=i
  1371.     WriteF(' R-\d',bigbox)
  1372.                         ENDIF
  1373.                         IF box.grnw>bigbox;bigbox:=box.grnw;movebox:=i
  1374.     WriteF(' G-\d',bigbox)
  1375.                         ENDIF
  1376.                         IF box.bluw>bigbox;bigbox:=box.bluw;movebox:=i
  1377.     WriteF(' B-\d',bigbox)
  1378.                         ENDIF
  1379. */
  1380.                     ENDIF
  1381.                 ENDFOR
  1382. ->    WriteF('\nbigbox=\d',bigbox)
  1383.                 swapboxes(bv,bv+(movebox*SIZEOF box))
  1384.                 
  1385.  
  1386. /*
  1387. WriteF('------\n')
  1388. FOR i:=0 TO boxes-1
  1389.     box:=bv+(i*SIZEOF box)
  1390.     WriteF('\d[4] \d[6] \d[6] (\d[3],\d[3],\d[3])\n',box.ind,box.colors,box.sum,box.redw,box.grnw,box.bluw)
  1391. ENDFOR
  1392. WriteF('------\n')
  1393. */
  1394.  
  1395.             ENDWHILE
  1396. break3:
  1397.             FOR bi:=0 TO (boxes-1)
  1398.                 box:=bv+(bi*SIZEOF box)
  1399.                 indx:=box.ind
  1400.                 clrs:=box.colors
  1401.                 r:=0;g:=0;b:=0;sum:=0
  1402.                 FOR i:=0 TO (clrs-1)
  1403.                     chi:=chv+((indx+i)*SIZEOF colorhist_item)
  1404.                     colo:=chi.color
  1405.                     tmp1:=chi.value
  1406. ->                    r:=r+((PPM_GETR(colo))*tmp1)
  1407. ->                    g:=g+((PPM_GETG(colo))*tmp1)
  1408. ->                    b:=b+((PPM_GETB(colo))*tmp1)
  1409. ->                    sum:=sum+tmp1
  1410.                     r:=r+((PPM_GETR(colo)))
  1411.                     g:=g+((PPM_GETG(colo)))
  1412.                     b:=b+((PPM_GETB(colo)))
  1413.                     sum:=sum+1
  1414.                 ENDFOR
  1415.                 r:=limit(r/sum,0,255)
  1416.                 g:=limit(g/sum,0,255)
  1417.                 b:=limit(b/sum,0,255)
  1418.                 chi:=colormap+(bi*SIZEOF colorhist_item)
  1419.                 chi.color:=PPM_ASSIGN(r,g,b)
  1420.             ENDFOR
  1421.         ENDIF
  1422.         Dispose(bv)
  1423.     ENDIF
  1424. ENDPROC colormap
  1425.  
  1426. PROC swapboxes(box1:PTR TO box,box2:PTR TO box)
  1427.     DEF tmp
  1428.     tmp:=box1.ind;        box1.ind:=box2.ind;                box2.ind:=tmp
  1429.     tmp:=box1.colors;    box1.colors:=box2.colors;    box2.colors:=tmp
  1430.     tmp:=box1.sum;        box1.sum:=box2.sum;                box2.sum:=tmp
  1431.     tmp:=box1.redw;        box1.redw:=box2.redw;            box2.redw:=tmp
  1432.     tmp:=box1.grnw;        box1.grnw:=box2.grnw;            box2.grnw:=tmp
  1433.     tmp:=box1.bluw;        box1.bluw:=box2.bluw;            box2.bluw:=tmp
  1434. ENDPROC
  1435.  
  1436. PROC computecolorhist(redbuf,grnbuf,blubuf,cols,rows,maxcolors,colorsP)
  1437.     DEF cht=0
  1438.     DEF chv=0
  1439.     cht:=computecolorhash(redbuf,grnbuf,blubuf,cols,rows,maxcolors,colorsP)
  1440.     IF cht
  1441.         chv:=colorhashtocolorhist(cht,maxcolors)
  1442.         freecolorhash(cht)
  1443.         RETURN chv
  1444.     ELSE
  1445.         RETURN 0
  1446.     ENDIF
  1447. ENDPROC
  1448.  
  1449. PROC computecolorhash(redbuf,grnbuf,blubuf,cols,rows,maxcolors,colorsP)
  1450.     DEF cht=0
  1451.     DEF pP=0
  1452.     DEF chl=0:PTR TO colorhist_list_item
  1453.     DEF col,row,hash,ccoolloorr
  1454.     cht:=alloccolorhash()
  1455.     IF cht
  1456.         PutLong(colorsP,0)
  1457.         row:=0
  1458.         REPEAT
  1459.             IF checkcancel(statwindow)
  1460.                 freecolorhash(cht)
  1461.                 Raise("canc")
  1462.             ENDIF
  1463.             IF (((row+3)/4)=(row/4))
  1464.                 IF statgauge THEN fuelgauge(statgauge,row,rows-1,stat.histogram_string)
  1465.             ENDIF
  1466.             col:=0
  1467.             REPEAT
  1468.                 ccoolloorr:=((PPM_PUTR(Char(redbuf+pP)) OR PPM_PUTG(Char(grnbuf+pP)) OR PPM_PUTB(Char(blubuf+pP))) AND $FEFEFE)
  1469.                 hash:=HASHPIXEL(ccoolloorr)
  1470.                 chl:=Long(cht+(hash*4))
  1471.                 WHILE (chl<>0)
  1472.                     IF (chl.ch.color=ccoolloorr)
  1473.                         JUMP break
  1474.                     ENDIF
  1475.                     chl:=chl.next
  1476.                 ENDWHILE
  1477. break:
  1478.                 IF (chl<>0)
  1479.                     chl.ch.value:=(chl.ch.value+1)
  1480.                 ELSE
  1481.                     PutLong(colorsP,Long(colorsP)+1)
  1482.                     IF Long(colorsP)>maxcolors
  1483.                         freecolorhash(cht)
  1484.                         RETURN 0
  1485.                     ENDIF
  1486. ->                    chl:=New(SIZEOF colorhist_list_item)
  1487.                     chl:=alloc(histopool,SIZEOF colorhist_list_item)
  1488.                     IF chl
  1489.                         chl.ch.color:=ccoolloorr
  1490.                         chl.ch.value:=1
  1491.                         chl.next:=Long(cht+(hash*4))
  1492.                         PutLong((cht+(hash*4)),chl)
  1493.                     ENDIF
  1494.                 ENDIF
  1495.             col:=col+1;pP:=pP+1;UNTIL col=cols
  1496.         row:=row+1;UNTIL row=rows
  1497.     ENDIF
  1498. ENDPROC cht
  1499.  
  1500. PROC alloccolorhash()
  1501.     DEF cht=0
  1502.     cht:=New((HASH_SIZE*4)+20)
  1503. ENDPROC cht
  1504.  
  1505. PROC colorhashtocolorhist(cht,maxcolors)
  1506.     DEF chv=0:PTR TO colorhist_item
  1507.     DEF chl=0:PTR TO colorhist_list_item
  1508.     DEF i,j
  1509.     chv:=New((maxcolors*SIZEOF colorhist_item)+20)
  1510.     j:=0
  1511.     FOR i:=0 TO (HASH_SIZE-1)
  1512.         chl:=Long(cht+(i*4))
  1513.         WHILE (chl<>0)
  1514.             PutLong(chv+(j*SIZEOF colorhist_item),chl.ch.color)
  1515.             PutLong(chv+4+(j*SIZEOF colorhist_item),chl.ch.value)
  1516. ->            WriteF('\n\h \d',chl.ch.color,chl.ch.value)
  1517.             j:=j+1
  1518.             chl:=chl.next
  1519.         ENDWHILE
  1520.     ENDFOR
  1521. ENDPROC chv
  1522.  
  1523. PROC freecolorhash(cht)
  1524.     DEF i
  1525.     DEF chl:PTR TO colorhist_list_item
  1526.     DEF chlnext
  1527.     i:=0
  1528.     deletepool(histopool)
  1529. /*    WHILE (i<HASH_SIZE)
  1530.         chl:=Long(cht+(i*4))
  1531.         WHILE (chl<>0)
  1532.             chlnext:=chl.next
  1533. ->            WriteF('(\z\h[2] \z\h[2] \z\h[2],\z\h[8])\n',PPM_GETR(chl.ch.color),PPM_GETG(chl.ch.color),PPM_GETB(chl.ch.color),chl.ch.value)
  1534.             Dispose(chl)
  1535.             chl:=chlnext
  1536.         ENDWHILE
  1537.         i:=i+1
  1538.     ENDWHILE*/
  1539.     Dispose(cht)
  1540. ENDPROC 0
  1541.  
  1542. PROC qsort(chv,l,r,and)
  1543.     DEF i,j,x,m1,m2
  1544. ->    RETURN
  1545. ->WriteF('>')
  1546. ->WriteF('\n\d',FreeStack())
  1547.     x:=((Long(chv+((Shr(l+r,1))*SIZEOF colorhist_item))) AND and)
  1548.     i:=l
  1549.     j:=r
  1550.     REPEAT
  1551.         WHILE (((Long(chv+(i++*SIZEOF colorhist_item))) AND and) < x)
  1552. ->            WriteF('I')
  1553.         ENDWHILE
  1554.         WHILE (x<((Long(chv+(j*SIZEOF colorhist_item))) AND and))
  1555.             j:=j-1
  1556. ->            WriteF('*')
  1557.         ENDWHILE
  1558.         IF (i-- <=j)
  1559. ->            WriteF('!')
  1560.             m1:=chv+(j*SIZEOF colorhist_item)
  1561.             m2:=chv+(i*SIZEOF colorhist_item)
  1562. /*            MOVE.L    j,D0
  1563.             MULU.L    #8,D0
  1564.             ADD.L        chv,D0
  1565.             MOVE.L    i,D1
  1566.             MULU.L    #8,D1
  1567.             ADD.L        chv,D1
  1568.             MOVE.L    D0,A0
  1569.             MOVE.L    D1,A1*/
  1570.             MOVE.L    m1,A0
  1571.             MOVE.L    m2,A1
  1572.  
  1573.             MOVE.L    (A0),D0
  1574.             MOVE.L    (A1),(A0)+
  1575.             MOVE.L    D0,(A1)+
  1576.             MOVE.L    (A0),D0
  1577.             MOVE.L    (A1),(A0)
  1578.             MOVE.L    D0,(A1)
  1579.             i:=i+1
  1580.             DEC j
  1581.         ENDIF
  1582.     UNTIL i>j
  1583.     IF l<j THEN qsort(chv,l,j,and)
  1584.     IF i<r THEN qsort(chv,i,r,and)
  1585. ->    WriteF('<')
  1586. ENDPROC
  1587. /*
  1588. PROC qsort(chv,l,r,and)
  1589.     DEF i,j,m1,m2,vand
  1590. ->    RETURN
  1591. ->WriteF('Q')
  1592.     IF (r>l)
  1593.         vand:=((Long(chv+(r*SIZEOF colorhist_item))) AND and)
  1594.  
  1595.         i:=l-1
  1596.         j:=r
  1597.         WHILE (1=1)
  1598.             m2:=TRUE
  1599.             REPEAT
  1600.                 i:=i+1
  1601.                 IF (((Long(chv+(i*SIZEOF colorhist_item))) AND and)>=vand) THEN m2:=FALSE
  1602.                 IF i>=r THEN m2:=FALSE
  1603. ->WriteF('i')
  1604.             UNTIL m2=FALSE
  1605.             m2:=TRUE
  1606.             REPEAT
  1607.                 j:=j-1
  1608.                 IF (((Long(chv+(j*SIZEOF colorhist_item))) AND and)<=vand) THEN m2:=FALSE
  1609.                 IF j<=l THEN m2:=FALSE
  1610. ->WriteF('j')
  1611.             UNTIL m2=FALSE
  1612.  
  1613.             IF (i>=j) THEN JUMP break6
  1614. ->WriteF('#')
  1615.             m1:=chv+(j*SIZEOF colorhist_item)
  1616.             m2:=chv+(i*SIZEOF colorhist_item)
  1617.             MOVE.L    m1,A0
  1618.             MOVE.L    m2,A1
  1619.  
  1620.             MOVE.L    (A0),D0
  1621.             MOVE.L    (A1),(A0)+
  1622.             MOVE.L    D0,(A1)+
  1623.             MOVE.L    (A0),D0
  1624.             MOVE.L    (A1),(A0)
  1625.             MOVE.L    D0,(A1)
  1626.             
  1627.         ENDWHILE
  1628. break6:
  1629. ->WriteF('*')
  1630.         IF (i<r)
  1631.             m1:=chv+(r*SIZEOF colorhist_item)
  1632.             m2:=chv+(i*SIZEOF colorhist_item)
  1633.             MOVE.L    m1,A0
  1634.             MOVE.L    m2,A1
  1635.  
  1636.             MOVE.L    (A0),D0
  1637.             MOVE.L    (A1),(A0)+
  1638.             MOVE.L    D0,(A1)+
  1639.             MOVE.L    (A0),D0
  1640.             MOVE.L    (A1),(A0)
  1641.             MOVE.L    D0,(A1)
  1642.         ENDIF
  1643.         qsort(chv,l,i-1,and)
  1644.         qsort(chv,i+1,r,and)
  1645.     ENDIF
  1646. ENDPROC
  1647. */
  1648. PROC doexchange(cmap,pen,r,g,b,uhp)
  1649.     DEF newpen
  1650.     newpen:=findcolorbytes(cmap,r,g,b,uhp)
  1651.     exchangecolorcmap(cmap,pen,newpen)
  1652. ENDPROC
  1653.  
  1654. PROC sizebox(box:PTR TO box,chv)
  1655.     DEF i,ptr:PTR TO colorhist_item
  1656.     DEF mr=255,mg=255,mb=255,xr=0,xg=0,xb=0
  1657.     DEF color,r,g,b
  1658.     ptr:=chv+(box.ind*SIZEOF colorhist_item)
  1659.     FOR i:=0 TO box.colors-1
  1660.         color:=ptr.color
  1661.         MOVE.L    color,D0
  1662.         MOVE.L    D0,D1
  1663.         AND.L        #$FF,D1
  1664.         MOVE.L    D1,b
  1665.         LSR.L        #8,D0
  1666.         MOVE.L    D0,D1
  1667.         AND.L        #$FF,D1
  1668.         MOVE.L    D1,g
  1669.         LSR.L        #8,D0
  1670.         MOVE.L    D0,D1
  1671.         AND.L        #$FF,D1
  1672.         MOVE.L    D1,r
  1673.         IF (r<mr) THEN mr:=r
  1674.         IF (g<mg) THEN mg:=g
  1675.         IF (b<mb) THEN mb:=b
  1676.         IF (r>xr) THEN xr:=r
  1677.         IF (g>xg) THEN xg:=g
  1678.         IF (b>xb) THEN xb:=b
  1679.         ptr:=ptr+SIZEOF colorhist_item
  1680.     ENDFOR
  1681.     box.redw:=xr-mr
  1682.     box.grnw:=xg-mg
  1683.     box.bluw:=xb-mb
  1684. ->    WriteF('\n (\d,\d,\d) \d',box.redw,box.grnw,box.bluw,box.colors)
  1685. ENDPROC
  1686.